#include <iostream>
#include <windows.h>
#include <mmsystem.h>
#pragma comment(lib, "winmm.lib")

class WavPlayer {
private:
    HWAVEOUT hWaveOut;
    WAVEFORMATEX wfx;
    WAVEHDR waveHeader;
    BYTE* waveData;
    DWORD waveSize;

public:
    WavPlayer() : hWaveOut(nullptr), waveData(nullptr), waveSize(0) {}
    ~WavPlayer() {
        if (hWaveOut) {
            waveOutClose(hWaveOut);
        }
        if (waveData) {
            delete[] waveData;
        }
    }

    bool Load(const char* filename) {
        FILE* file = fopen(filename, "rb");
        if (!file) {
            std::cerr << "无法打开文件" << std::endl;
            return false;
        }

        // 读取RIFF头
        char chunkId[4];
        fread(chunkId, sizeof(char), 4, file);
        if (strncmp(chunkId, "RIFF", 4) != 0) {
            std::cerr << "无效的WAV文件格式" << std::endl;
            fclose(file);
            return false;
        }

        fseek(file, 4, SEEK_CUR); // 跳过文件大小
        fread(chunkId, sizeof(char), 4, file);
        if (strncmp(chunkId, "WAVE", 4) != 0) {
            std::cerr << "无效的WAV文件格式" << std::endl;
            fclose(file);
            return false;
        }

        // 读取fmt块
        while (true) {
            fread(chunkId, sizeof(char), 4, file);
            DWORD chunkSize;
            fread(&chunkSize, sizeof(DWORD), 1, file);
            if (strncmp(chunkId, "fmt ", 4) == 0) {
                fread(&wfx, sizeof(WAVEFORMATEX), 1, file);
                fseek(file, chunkSize - sizeof(WAVEFORMATEX), SEEK_CUR);
                break;
            } else {
                fseek(file, chunkSize, SEEK_CUR);
            }
        }

        // 读取data块
        while (true) {
            fread(chunkId, sizeof(char), 4, file);
            DWORD chunkSize;
            fread(&chunkSize, sizeof(DWORD), 1, file);
            if (strncmp(chunkId, "data", 4) == 0) {
                waveSize = chunkSize;
                waveData = new BYTE[waveSize];
                fread(waveData, sizeof(BYTE), waveSize, file);
                break;
            } else {
                fseek(file, chunkSize, SEEK_CUR);
            }
        }

        fclose(file);
        return true;
    }

    bool Play() {
        if (waveOutOpen(&hWaveOut, WAVE_MAPPER, &wfx, 0, 0, CALLBACK_NULL) != MMSYSERR_NOERROR) {
            std::cerr << "无法打开音频输出设备" << std::endl;
            return false;
        }

        waveHeader.lpData = reinterpret_cast<LPSTR>(waveData);
        waveHeader.dwBufferLength = waveSize;
        waveHeader.dwBytesRecorded = 0;
        waveHeader.dwUser = 0;
        waveHeader.dwFlags = 0;
        waveHeader.dwLoops = 0;
        waveHeader.lpNext = nullptr;
        waveHeader.reserved = 0;

        if (waveOutPrepareHeader(hWaveOut, &waveHeader, sizeof(WAVEHDR)) != MMSYSERR_NOERROR) {
            std::cerr << "无法准备音频头" << std::endl;
            return false;
        }

        if (waveOutWrite(hWaveOut, &waveHeader, sizeof(WAVEHDR)) != MMSYSERR_NOERROR) {
            std::cerr << "无法播放音频" << std::endl;
            return false;
        }

        // 等待播放完成
        while (waveOutUnprepareHeader(hWaveOut, &waveHeader, sizeof(WAVEHDR)) == WAVERR_STILLPLAYING) {
            Sleep(100);
        }

        return true;
    }
};

int main() {
    WavPlayer player;
    if (player.Load("16bit_mono_44_1_khz.wav")) {
        if (player.Play()) {
            std::cout << "音频播放完成" << std::endl;
        }
    }
    return 0;
}